<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>1.2变量作用域与解构赋值</title>
	<!--<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>-->
</head>
<body>
	<script>
		//测试函数的作用域;
		//js的函数在查找变量时先从自身函数开始
		//从内向外查找，如果内部变量和外部变量重名
		//则内部变量将屏蔽外部变量
		function outer() {
			var x = 1;
			function inner() {
				var x = 2;
				console.log("inner():" + x);
			}
			inner();
			console.log("outer():" + x);
		}

		outer();
		//变量提升。
		//JavaScript的函数定义有个特点，它会先扫描整个函数体的语句，把所有申明的变量“提升”到函数顶部：
		function up() {
			var x = "Hello," + y;
			console.log(x);
			var y = "World";
		}
		//等价于
		// function foo() {
		// 	var x = 'Hello, ' + y;
		// 	console.log(x);
		// 	var y = 'Bob';
		// }
		up();

		//全局作用域：不在任何函数内定义的变量就是全局作用域。
		//js有默认的“全局对象” window 全局作用于绑定到window一个属性

		var course = "Learn JavaScript";
		console.log(course);
		console.log(window.course);

		//foo 是 window对象的全局变量.
		//即：顶层函数的定义也是全局变量
		var foo = function () {
			console.log("foo");
		}
		foo();
		window.foo();

		//名字空间(namespace);
		//为了避免多个js之间定义了相同的“顶层函数” 和 “全局变量”。从而引起冲突
		//js 引入了 名字空间的概念，为不同的js,定义不同的namespace避免冲突的产生。

		var MyApp = {};
		MyApp.name = "欧阳";
		MyApp.version = "1.0";
		MyApp.foo = function () {
			return "foo";
		}

		//局部作用域
		//由于js的局部作用域的作用范围在函数的内部，我们在
		//for循环的时候无法定义具有局部作用域的变量;
		//为了解决“块级作用域”,es6 引入let

		//申明一个常量
		//js在es6 以前无法申明一个常量 es6 引入了const关键字来申明常量
		// const 和 let 一样都具有块级作用域
		const PI = 3.14;

		//解构赋值 : 可以对一组变量进行赋值 es6 新特性
		// 对多个变量同时赋值
		var [x,y,z] = ["I","Hello","john"];
		console.log("x:" + x + ",y:" + y + ",z:" + z);

		//嵌套赋值
		var [a,[b,c]] = [1,[3,7]];
		console.log("a:" + a + ",b:" + b + ",c:" + c);

		//忽略某些元素赋值
		let [, , i] = [5, , , ];
		console.log("i:" + i);

		var person = {
			name: '小明',
			age: 20,
			gender: 'male',
			passport: 'G-12345678',
			school: 'No.4 middle school',
			address: {
				city:'BeiJing',
				street:'No.1 Road',
			}
		};
		var {name, age, school} = person;
		var {name,passport,address:{city}} = person;
		console.log("name:" + name + ",age:" + age + ",school:" + school);
		console.log("name:" + name + ",age:" + age + ",city:" + city + ",passport:" + passport);

		let {m,n} = {name:"小明",m:"hello",n:"world"};
		console.log("m:" + m);
		console.log("n:" + n);

		//解构赋值的使用场景
		let x1 = 1, y1 = 2;
		//交换值
		[x1,y1] = [y1,x1];
		console.log("x1:" + x1 + ",y1:" + y1);

		//如果一个函数把对象作为参数，那么可以把对象的属性绑定到变量中
		function buildDate({year,month,day,hour=0,minute=0,second=0}) {
			return new Date(year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second);
		}
		var xxx = buildDate({year:2018,month:5,day:3});
		console.log("xxx:" + xxx);
	</script>
</body>
</html>